//
//  CreateJobInstallAddressView.swift
//  GreenDeal
//
//  Created by Moennig Q on 2/3/2023.
//

import UIKit
import SnapKit
import RxSwift
import RxCocoa
class CreateJobInstallAddressView: CreateJobBaseView {
    var viewModel: CreateJobInstallAddressViewModel!
    let editAddressView = PhysicalAddressView()
    let specailAddressView = CreateJobSpecialAddressView()
    var addADifferentPostalAddressBtn: LayoutButton = {
        let view = LayoutButton(.left)
        view.setBtnInfo(R.string.localizable.addADifferentPostalAddress(),hexStr: Constant.ThemeColorHexStr, textFont: R.font.interMedium(size: 14),imageName: "createjob_install_address_special_address_add")
        view.tag = 0
        return view
    }()
    
    lazy var postalAddressView: PhysicalAndPOBoxAddressView = {
        let view = PhysicalAndPOBoxAddressView(leftRightMargin: Constant.LeftRightMargin, topBottomMargin: Constant.TopBottomMargin,postalAddressFlag: true)
        view.drawBorder(backHexStr: "#FFFFFFFF", borderHexStr: "#292D3233")
        return view
    }()
    override func setUpContentView() {
        //title
        let addressLabel = ContentLabel()
        addressLabel.text = R.string.localizable.address()
        contentView.addSubview(addressLabel)
        addressLabel.snp.makeConstraints { make in
            make.top.equalTo(Constant.AllOutMargin)
            make.left.equalTo(Constant.AllOutMargin)
            make.height.width.greaterThanOrEqualTo(0)
        }
        //编辑地址区域
        contentView.addSubview(editAddressView)
        editAddressView.snp.makeConstraints { make in
            make.top.equalTo(addressLabel.snp.bottom).offset(Constant.TitleTextMargin)
            make.left.equalTo(addressLabel)
            make.right.equalTo(-Constant.AllOutMargin)
            make.height.greaterThanOrEqualTo(0)
        }
        //special address
        contentView.addSubview(specailAddressView)
        specailAddressView.snp.makeConstraints { make in
            make.top.equalTo(editAddressView.snp.bottom).offset(Constant.SectionTopMargin)
            make.left.right.equalTo(editAddressView)
            make.height.greaterThanOrEqualTo(0)
            make.bottom.lessThanOrEqualToSuperview()
        }
        //sameAsPostalAddressBtn
        contentView.addSubview(addADifferentPostalAddressBtn)
        addADifferentPostalAddressBtn.snp.makeConstraints { make in
            make.top.equalTo(specailAddressView.snp.bottom).offset(Constant.SectionTopMargin)
            make.left.equalTo(editAddressView)
            make.height.width.greaterThanOrEqualTo(0)
            make.bottom.equalTo(-Constant.AllOutMargin)
        }
        //切换physical或po box要跳转到相应的位置
        self.postalAddressView.scrollToAddAddressViewClosure = {[weak self] in
            guard let strongSelf = self else {return}
            strongSelf.layoutIfNeeded()//会强制重绘并等待完成。
            strongSelf.scrollView.scrollToView(view: strongSelf.addADifferentPostalAddressBtn, animated: true)
        }
        addADifferentPostalAddressBtn.addTarget(self, action: #selector(addADifferentPostalAddressBtnClick(_:)), for: UIControl.Event.touchUpInside)
    }
    @objc func addADifferentPostalAddressBtnClick(_ sender: LayoutButton){
        if sender.tag == 0{//增加postal adress
            self.viewModel.sameAsPostalAddress = false
            self.addPostalAddressView()
            //增加的时候，滚动Postal address的位置，方便用户增加Postal地址
            self.layoutIfNeeded()//会强制重绘并等待完成。
            self.scrollView.scrollToView(view: addADifferentPostalAddressBtn, animated: true)
        }else{//删除postal adress
            self.viewModel.sameAsPostalAddress = true
            self.delPostalAddressView()
        }
    }
    //
    func setData(_ model: CreateJobInstallAddressViewModel,editFlag: Bool = false){
        self.viewModel = model
        self.editAddressView.setData(self.viewModel.installAddress)
        self.postalAddressView.setData(self.viewModel.postalAddress)
        //specail address
        self.specailAddressView.setData(self.viewModel)
        //same as postal address
        if self.viewModel.sameAsPostalAddress {
            self.addADifferentPostalAddressBtn.tag = 0//表示不增加
        }else{
            self.addADifferentPostalAddressBtn.tag = 1
        }
        self.showPostalAddressView()
        //
        self.checkEverythingValid()
        //
        if editFlag {//
            self.validateAllRequiredFieldWhenEdit()
        }
    }
    
    //MARK: - 只用于已创建Job的信息编辑， 进入编辑界面如果save 按钮不可用，要给与相应提示
    private func validateAllRequiredFieldWhenEdit(){
        //1.install address
        self.editAddressView.validateAllRequiredFieldWhenEdit()
        if self.viewModel.sameAsPostalAddress == false{
            self.postalAddressView.validateAllRequiredFieldWhenEdit()
        }
    }
    private func showPostalAddressView(){
        if self.addADifferentPostalAddressBtn.tag == 1 {//勾选表示和上边的地址一样，不显示下边的postalAddressView
            self.addPostalAddressView()
        }else{//不勾选表示，编辑自己的地址
            self.delPostalAddressView()
        }
    }
    //MARK: - 增加post address view
    private func addPostalAddressView(){
        addADifferentPostalAddressBtn.tag = 1
        addADifferentPostalAddressBtn.setBtnInfo(R.string.localizable.removeDifferentPostalAddress(),hexStr: "#DD890B", textFont: R.font.interMedium(size: 14),imageName: "createjob_install_address_special_address_del")
        addADifferentPostalAddressBtn.snp.remakeConstraints { make in
            make.top.equalTo(specailAddressView.snp.bottom).offset(Constant.SectionTopMargin)
            make.left.equalTo(editAddressView)
            make.right.lessThanOrEqualTo(editAddressView)
            make.height.greaterThanOrEqualTo(0)
        }
        //
        contentView.addSubview(postalAddressView)
        postalAddressView.snp.makeConstraints { make in
            make.top.equalTo(addADifferentPostalAddressBtn.snp.bottom).offset(Constant.TitleTextMargin)
            make.left.right.equalTo(editAddressView)
            make.height.greaterThanOrEqualTo(0)
            make.bottom.equalTo(-Constant.TopBottomMargin)
        }
    }
    
    //MARK: - 增加post address view
    private func delPostalAddressView(){
        //
        addADifferentPostalAddressBtn.tag = 0
        addADifferentPostalAddressBtn.setBtnInfo(R.string.localizable.addADifferentPostalAddress(),hexStr: Constant.ThemeColorHexStr, textFont: R.font.interMedium(size: 14),imageName: "createjob_install_address_special_address_add")
        addADifferentPostalAddressBtn.snp.remakeConstraints { make in
            make.top.equalTo(specailAddressView.snp.bottom).offset(Constant.SectionTopMargin)
            make.left.equalTo(editAddressView)
            make.right.lessThanOrEqualTo(editAddressView)
            make.height.greaterThanOrEqualTo(0)
            make.bottom.equalTo(-Constant.TopBottomMargin)
        }
        if let _ = postalAddressView.superview {
            postalAddressView.removeFromSuperview()
        }
        self.postalAddressView.changeAddressType(.none)
    }
    //MARK: - 必填项数据绑定控制continue btn是否可用
    private func checkEverythingValid(){
        //1.install address
        let installAddressUnitTypeValid = self.viewModel.installAddress.rx.observe(String.self, "unit_type").map({($0 ?? "").count > 0}).share(replay: 1)
        let installAddressUnitNoValid = self.viewModel.installAddress.rx.observe(String.self, "unit_number").map({($0 ?? "").count > 0}).share(replay: 1)
        let installAddressStreetTypeValid = self.viewModel.installAddress.rx.observe(String.self, "street_type").map({($0 ?? "").count > 0}).share(replay: 1)
        let installAddressStreetNameValid = self.viewModel.installAddress.rx.observe(String.self, "street_name").map({($0 ?? "").count > 0}).share(replay: 1)
        let installAddressStreetNumberValid = self.viewModel.installAddress.rx.observe(String.self, "street_number").map({($0 ?? "").count > 0}).share(replay: 1)
        let installAddressStateValid = self.viewModel.installAddress.rx.observe(String.self, "state").map({($0 ?? "").count > 0}).share(replay: 1)
        let installAddressSuburbValid = self.viewModel.installAddress.rx.observe(String.self, "suburb").map({($0 ?? "").count > 0}).share(replay: 1)
        let installAddressPostcodeValid = self.viewModel.installAddress.rx.observe(String.self, "post_code").map({($0 ?? "").count > 0}).share(replay: 1)
        //combine
        let installAddressValid = Observable.combineLatest(
            installAddressUnitTypeValid,
            installAddressUnitNoValid,
            installAddressStreetTypeValid,
            installAddressStreetNameValid,
            installAddressStreetNumberValid,
            installAddressStateValid,
            installAddressSuburbValid,
            installAddressPostcodeValid
          ) { ($0 && $1 || !$0 && !$1) && $2 && $3 && $4 && $5 && $6 && $7}
          .share(replay: 1)
        //2.same as post address
        let sameAsPostAddressValid = self.viewModel.rx.observe(Bool.self, "sameAsPostalAddress").map({$0 ?? false}).share(replay: 1)
        let physicalAddressTypeValid = self.viewModel.postalAddress.rx.observe(String.self, "address_type_value").map({($0 ?? "") == AddressType.physical.rawValue}).share(replay: 1)
        let poBoxAddressTypeValid = self.viewModel.postalAddress.rx.observe(String.self, "address_type_value").map({($0 ?? "") == AddressType.poBox.rawValue}).share(replay: 1)
        //2.1 post Physical Address
        let postPhysicalAddressUnitTypeValid = self.viewModel.postalAddress.physicalAddress.rx.observe(String.self, "unit_type").map({($0 ?? "").count > 0}).share(replay: 1)
        let postPhysicalAddressUnitNoValid = self.viewModel.postalAddress.physicalAddress.rx.observe(String.self, "unit_number").map({($0 ?? "").count > 0}).share(replay: 1)
        let postPhysicalAddressStateValid = self.viewModel.postalAddress.physicalAddress.rx.observe(String.self, "state").map({($0 ?? "").count > 0}).share(replay: 1)
        let postPhysicalAddressSuburbValid = self.viewModel.postalAddress.physicalAddress.rx.observe(String.self, "suburb").map({($0 ?? "").count > 0}).share(replay: 1)
        let postPhysicalAddressPostcodeValid = self.viewModel.postalAddress.physicalAddress.rx.observe(String.self, "post_code").map({($0 ?? "").count > 0}).share(replay: 1)
        //combine
        let postPhysicalAddressValid = Observable.combineLatest(
            postPhysicalAddressUnitTypeValid,
            postPhysicalAddressUnitNoValid,
            postPhysicalAddressStateValid,
            postPhysicalAddressSuburbValid,
            postPhysicalAddressPostcodeValid
          ) {
              ($0 && $1 || !$0 && !$1) && $2 && $3 && $4
          }
          .share(replay: 1)
        //2.1 po box
        let poDeliverNumberValid = self.viewModel.postalAddress.rx.observe(String.self, "delivery_number").map({($0 ?? "").count > 0}).share(replay: 1)
        let poBoxStateValid = self.viewModel.postalAddress.rx.observe(String.self, "state").map({($0 ?? "").count > 0}).share(replay: 1)
        let poBoxSuburbValid = self.viewModel.postalAddress.rx.observe(String.self, "suburb").map({($0 ?? "").count > 0}).share(replay: 1)
        let poBoxPostcodeValid = self.viewModel.postalAddress.rx.observe(String.self, "post_code").map({($0 ?? "").count > 0}).share(replay: 1)
        //合并
        let poBoxValid = Observable.combineLatest(
            poDeliverNumberValid,
            poBoxStateValid,
            poBoxSuburbValid,
            poBoxPostcodeValid
          ) { $0 && $1 && $2 && $3}
          .share(replay: 1)
        //3.everthing valid
        let everythingValid = Observable.combineLatest(
            installAddressValid,
            sameAsPostAddressValid,
            physicalAddressTypeValid,
            postPhysicalAddressValid,
            poBoxAddressTypeValid,
            poBoxValid
        ) {
            if $0 && ($1 || (!$1 && $2 && $3) || (!$1 && $4 && $5)){
                return true
            }else{
                return false
            }
        }
          .share(replay: 1)
        //
        everythingValid.subscribe { [weak self] (valid) in
            guard let strongSelf = self else {return}
            if valid {
                strongSelf.continueBtn.enableBtn()
            }else{
                strongSelf.continueBtn.disableBtn()
            }
        }.disposed(by: self.disposeBag)
    }
}
